/**
 * 初始化系统权限
 * 1. 在前端定义权限配置列表
 * 2. 加载用户所拥有的权限列表
 * 3. 缓存权限列表
 * 4. 过滤得到需要渲染的菜单列表
 * 5. 根据菜单列表渲染菜单栏
 * 6. 提供函数进行元素级控制
 * @author rxliuli
 */
;(async () => {
    const realmSet = rx.arrayToMap(await sysMenuApi.loadSysMenuList(), 'permission')
    /**
     * 注册一个全局自定义指令 `v-realm`
     * 使用示例：
     * v-realm="''abc''"
     * v-realm="'['abc']'"
     */
    Vue.directive('realm', {
        bind(el, binding) {
            const result = realmSet && realmSet.size > 0 && binding.value.split(',')
                .filter(rx.CombinedPredicate.not(rx.StringValidator.isBlank))
                .map(s => s.trim())
                .every(s => realmSet.has(s))
            if (!result) {
                el.style.display = 'none'
            }
        },
    })
})()

window.addEventListener('load', async () => {
    // sysMenuApi.loadSysMenuList.clear()
    debugger
    const sysMenuList = await sysMenuApi.loadSysMenuList()

    // diff 权限列表
    const map = rx.groupBy(sysMenuList, ({menuType}) => menuType)
    // let realmSet = new Set((map.get(SysMenu.MenuTypePermission) || []).map(({permission}) => permission))
    const menuList = map.get(SysMenu.MenuTypeMenu).filter(({isShow}) => isShow === 1)
    const idMenuMap = rx.arrayToMap(menuList, ({id}) => id)
    const node = rx.listToTree(menuList)

    /**
     * 渲染菜单树节点
     * 确定元素种类 1. 根节点，ul 2. 文件夹节点 li > a 3. 末端节点 li > a
     * 自定义组件，递归渲染树
     */
    const SessionCacheKey = 'SessionCacheKey'
    let scrollBarHeight
    Vue.component('TreeItem', {
        template: '#item-template',
        props: {
            item: Object,
        },
        data() {
            return {
                isOpen: false,
            }
        },
        computed: {
            isFolder() {
                return !rx.ArrayValidator.isEmpty(this.item.child)
            },
        },
        methods: {
            toggle() {
                scrollBarHeight = document.documentElement.scrollTop
                if (this.isFolder) {
                    this.isOpen = !this.isOpen
                }
            },
            view() {
                sessionStorage.setItem(SessionCacheKey, this.item.id)
                forward(this.item.link)
            },
        },
        async mounted() {
            const {accessPath, params} = rx.parseUrl(location.href)
            if (accessPath === '/') {
                return
            }
            let id = sessionStorage.getItem(SessionCacheKey)
            if (idMenuMap.get(parseInt(id)) === undefined) {
                return
            }
            let pagePath = String().concat('/', params.get('pagePath'))
            if (id && idMenuMap.get(parseInt(id)).link === pagePath) {
                const sysMenu = idMenuMap.get(parseInt(id))
                this.isOpen = sysMenu.id === this.item.id || new Set(sysMenu.parentPath.split(',').slice(1).map(id => parseInt(id))).has(this.item.id)
                return
            }
            const linkSysMenuMap = rx.arrayToMap(menuList, ({link}) => link)
            const sysMenu = linkSysMenuMap.get(pagePath.toString())
            if (sysMenu) {
                this.isOpen = sysMenu.id === this.item.id || new Set(sysMenu.parentPath.split(',').slice(1).map(id => parseInt(id))).has(this.item.id)
                sessionStorage.setItem(SessionCacheKey, sysMenu.parentPath)
                return
            }
            const parentPath = sessionStorage.getItem(SessionCacheKey)
            if (!parentPath) {
                return
            }
            this.isOpen = new Set(parentPath.split(',').slice(1).map(id => parseInt(id))).has(this.item.id)
        },
    })

    // rx.watch(() => scrollBarHeight, () => document.documentElement.scrollTop = scrollBarHeight, 10)

    const menuTree = new Vue({
        el: '#menu-tree',
        data() {
            return {
                item: node,
            }
        },
    })
})
